
package com.hlkj.pay.task;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.hlkj.framework.common.pojo.PageResult;
import com.hlkj.framework.common.util.collection.CollectionUtils;
import com.hlkj.pay.dto.merchant.MerchantInfoQueryDto;
import com.hlkj.pay.dto.merchant.NoticePageQueryDto;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.infrastructure.model.merchant.MerchantInfoDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantNoticeDO;
import com.hlkj.pay.infrastructure.model.merchant.NoticeDO;
import com.hlkj.pay.service.merchant.IMerchantService;
import com.hlkj.pay.service.merchant.INoticeService;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2024/10/29 10:43
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class MerchantNoticeTasks {

    private final INoticeService noticeService;

    private final IMerchantService merchantService;

    @Value("${server.port:8020}")
    private String serverPort;

    @Value("${hlkj.task.port:8020}")
    private String taskPort;

    @Scheduled(cron = "0 1 * * * *")
    public void cronTask() {
        if (!serverPort.equals(taskPort)) {
            log.info("当前task port 非目标port serverPort:{},taskPort:{}", serverPort, taskPort);
            return;
        }
        LocalDate localDate = LocalDate.now();
        long startQueryTime = LocalDateTime.of(localDate.getYear(), localDate.getMonth(), localDate.getDayOfMonth(), 0, 0, 0).atZone(ZoneId.of("Asia/Shanghai")).toInstant()
                .toEpochMilli();
        long endQueryTime = LocalDateTime.of(localDate.getYear(), localDate.getMonth(), localDate.getDayOfMonth(), 23, 59, 59).atZone(ZoneId.of("Asia/Shanghai")).toInstant()
                .toEpochMilli();

        log.info("公告同步到商户公告 date:{}", LocalDateTime.now());
        NoticePageQueryDto noticePageQueryDto = new NoticePageQueryDto();
        noticePageQueryDto.setStatus(CommonEnum.YES_NO_TYPE.YES.getCode());
        noticePageQueryDto.setStartQueryTime(startQueryTime);
        noticePageQueryDto.setEndQueryTime(endQueryTime);
        noticePageQueryDto.setPageNo(1);
        noticePageQueryDto.setPageSize(Integer.MAX_VALUE);
        noticePageQueryDto.setSyncType(CommonEnum.YES_NO_TYPE.NO.getCode());
        PageResult<NoticeDO> noticeDOPageResult = noticeService.queryPage(noticePageQueryDto);
        List<NoticeDO> list = noticeDOPageResult.getList();
        if (CollectionUtils.isEmpty(list)) {
            log.info("当天没有需要同步的公告 date:{}", LocalDateTime.now());
            return;
        }
        // 按照类型进行分组
        Map<Integer, List<NoticeDO>> noticeMap = list.stream().collect(Collectors.groupingBy(noticeDO -> noticeDO.getPublishType()));
        MerchantInfoQueryDto merchantInfoQueryDto = new MerchantInfoQueryDto();
        merchantInfoQueryDto.setPageNo(1);
        merchantInfoQueryDto.setPageSize(Integer.MAX_VALUE);
        List<MerchantNoticeDO> merchantNoticeList = new ArrayList<>(list.size() * 2);
        noticeMap.forEach((key, value) -> {
            MerchantEnum.NOTICE_PUBLISH_TYPE publishType = MerchantEnum.NOTICE_PUBLISH_TYPE.from(key);
            List<MerchantInfoDO> merchantInfoDOList = null;
            switch (publishType) {
                case ALL:
                    merchantInfoDOList = merchantService.queryList(merchantInfoQueryDto);
                    break;
                case MERCHANT:
                    merchantInfoQueryDto.setSnType(MerchantEnum.MERCHANT_SN_TYPE.MERCHANT.getCode());
                    merchantInfoDOList = merchantService.queryList(merchantInfoQueryDto);
                    break;
                case AGENT:
                    merchantInfoQueryDto.setSnType(MerchantEnum.MERCHANT_SN_TYPE.AGENT.getCode());
                    merchantInfoDOList = merchantService.queryList(merchantInfoQueryDto);

                    break;
            }
            if (!CollectionUtils.isEmpty(merchantInfoDOList)) {
                List<MerchantInfoDO> finalMerchantInfoDOList = merchantInfoDOList;
                value.stream().forEach(noticeDO -> {
                    finalMerchantInfoDOList.stream().forEach(merchantInfoDO -> {
                        MerchantNoticeDO merchantNoticeDO = new MerchantNoticeDO();
                        merchantNoticeDO.setNoticeId(noticeDO.getId());
                        merchantNoticeDO.setSn(merchantInfoDO.getSn());
                        merchantNoticeDO.setStatus(CommonEnum.YES_NO_TYPE.NO.getCode());
                        merchantNoticeList.add(merchantNoticeDO);
                    });
                });
            }
        });
        if (!CollectionUtils.isEmpty(merchantNoticeList)) {
            noticeService.addMerchantNotice(merchantNoticeList);
        }
        List<Long> ids = list.stream().map(noticeDO -> noticeDO.getId()).collect(Collectors.toList());
        noticeService.updateSyncType(ids, CommonEnum.YES_NO_TYPE.YES);
    }

}
